<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>

// socket封装类
class SocketManager {
    socketMsgQueue = [];

    isOpen = false;

    messageCbs = [];

    constructor(url) {
        if (!url) {
            console.error('SocketManager: url is required');
            return;
        }
        this.url = url;
        this.init();
    // 判断是否有url  的存在，如果没有就return，否则执行init () 方法;
    }

    init() {
    // 创建WebSocket 链接：
        this.socketInstance = new WebSocket(this.url);
        // 打开链接并发送数据：
        this.socketInstance.onopen = () => {
            this.isOpen = true;
            for (let i = 0; i < this.socketMsgQueue.length; i += 1) {
                this.sendMessage(this.socketMsgQueue[i]);
            }
            this.socketMsgQueue.length = 0;
        };

        this.socketInstance.onmessage = (e) => {
            for (let i = 0; i < this.messageCbs.length; i += 1) {
                this.messageCbs[i](e.data);
            }
        };

        this.socketInstance.onclose = () => {
            this.destroy();
            this.init();
        };
    }

    // 调用的回调，这个地方比较绕，我想了大半天！！！和上述的onmessage 时间相对应
    // 的。我们调用的时候，将一个函数出入，所以此时数组中保存的多个函数！！！所以在
    // onmessage 中,我们拿到的e.data 就是数据使用for 循环，调用每一个函数！！！
    registerMessage(cb) {
        if (typeof cb === 'function') {
            this.messageCbs.push(cb);
        }
    }

    // 发送数据，可通过this._isOpen 来判断是否打开了长链接；
    sendMessage(msg) {
        if (this.isOpen) {
            this.socketInstance.send(msg);
        } else {
            this.socketMsgQueue.push(msg);
        }
    }

    // 销毁此次长链接
    destroy() {
        this.socketInstance.close();
        this.socketInstance.onmessage = null;
        this.socketInstance.onopen = null;
        this.socketInstance.onclose = null;
        delete this.socketInstance;
    }
}
const ws = new SocketManager('ws://localhost:8899/websocket')
ws.sendMessage(JSON.stringify(
    {
        param:{
            a:1,
            b:2
        }
    }
));
// ws.sendMessage('我是发送的消息1');
// ws.sendMessage('我是发送的消息2');
// ws.sendMessage('我是发送的消息3');

</script>
</html>